/*
 * Tabla.cpp
 *
 *  Created on: Oct 12, 2012
 *      Author: romina
 */

#include "Tabla.h"

Tabla::Tabla(string path):ArchivoDeTexto(path, W) {

	this->tamanio = 0;
	this->archivo.width(ANCHO_TABLA);
	this->archivo << dec << this->tamanio << '|';
	this->archivo.close();

}

int Tabla::get_tamanio(){
	return this->tamanio;
}

//string Tabla::formatear_tamanio(){
//	stringstream cad;
//	cad << dec << this->tamanio << '|';
//	return cad.str();
//}


void Tabla::calcular_tamanio(){
	this->archivo.open(path.c_str(), std::fstream::in | std::fstream::out);
	string s;
	stringstream ss;
	getline(this->archivo, s, '|');
	ss << s;
	ss >> dec >> this->tamanio;
	this->archivo.close();
}

void Tabla::referencia_inicial(int id_cubo){
	this->tamanio = 1;
	this->archivo.open(path.c_str(), std::fstream::in | std::fstream::out);
	this->archivo.width(8);
	this->archivo << dec << this->tamanio << '|';
	this->archivo << ' ' << dec << id_cubo;
	this->archivo.close();

}

void Tabla::reemplazar(int posicion, int id_cubo_nuevo){

	ofstream arch_tmp;
	string s;
	int num_cubo;
	int contador = 0;
	string path_tmp = PATH_TABLA_TMP;

	this->archivo.open(path.c_str(), std::fstream::in | std::fstream::out);
	arch_tmp.open(path_tmp.c_str());

	arch_tmp.width(ANCHO_TABLA);
	arch_tmp << dec << this->tamanio << '|';

	getline(this->archivo, s, '|');

	while (contador != this->tamanio) {
		this->archivo >> num_cubo;

	    if (contador == posicion) {
	    	arch_tmp << ' ' << dec << id_cubo_nuevo;
	    }
	    else{
	    	arch_tmp << ' ' << dec << num_cubo;
	    }

	   ++ contador;
	}

//	while (contador != this->tamanio) {
//		this->archivo >> num_cubo;
//		arch_tmp << ' ' << dec << num_cubo;
//	    ++ contador;
//	}

	this->archivo.close();
	arch_tmp.close();

	remove(this->path.c_str());
	rename(path_tmp.c_str(),this->path.c_str());

}

void Tabla::reemplazar_desde(int pos_inicial, int id_cubo, int dispersion){
    ofstream arch_tmp;
    string s;
    int pos_aux, pos;
    int contador = 0;
    int salto = dispersion;
    string path_tmp = PATH_TABLA_TMP;

	this->archivo.open(path.c_str(), std::fstream::in | std::fstream::out);
    arch_tmp.open(path_tmp.c_str());
    arch_tmp.width(ANCHO_TABLA);
    arch_tmp << dec << this->tamanio << '|';

    getline(this->archivo, s, '|');

    pos = pos_inicial;
    pos_aux = pos_inicial - salto;
    while (pos_aux >= 0) {
            pos = pos_aux;
            pos_aux = pos - salto;
    }

    while (contador != this->tamanio) {
    	this->archivo >> s;
        if (contador == pos) {
        	arch_tmp << ' ' << dec << id_cubo;
            pos += salto;
        }
        else
        	arch_tmp << ' ' << dec << s;
        ++ contador;
    }

	this->archivo.close();
	arch_tmp.close();

	remove(this->path.c_str());
	rename(path_tmp.c_str(),this->path.c_str());



}

void Tabla::duplicar(){

	string s;
	string duplicado = "";
	int contador = 0;

	this->archivo.open(path.c_str(), std::fstream::in | std::fstream::out);

	getline(this->archivo, s, '|');

	while(contador != this->tamanio){
		this->archivo >> s;
		duplicado.append(' ' + s);
//		pos = this->archivo.tellp();
//		this->archivo.seekg(0, fstream::end);
//		this->archivo << ' ' << s;
		++ contador;
//		this->archivo.seekp(pos, fstream::cur);
	}

	this->archivo.seekg(0, fstream::end);
	this->archivo << duplicado;
	this->tamanio *= 2;
	this->archivo.seekg(0, fstream::beg);
	this->archivo.width(8);
	this->archivo << dec << this->tamanio << '|';
	this->archivo.close();
}

int Tabla::get_id_cubo(int posicion){

    string s;
    int id_cubo;
    int contador = 0;
    this->archivo.open(path.c_str(), std::fstream::in | std::fstream::out);
    getline(this->archivo, s, '|');

    while (contador != posicion) {

        this->archivo >> id_cubo;
        ++ contador;
    }

    this->archivo >> id_cubo;
    this->archivo.close();
    return id_cubo;
}

bool Tabla::vacia(){
	return this->tamanio == 0;
}

string Tabla::toString(){

	string cadena = "";
    this->archivo.open(this->path.c_str(), std::fstream::in | std::fstream::out);

    cadena = this->obtenerLinea();

    this->archivo.close();

    return cadena;
}

Tabla::~Tabla() {
}

